아래의 표와 같이 그룹을 user_id
로 했을 때 user_id
가 1인 경우 level 3, user_id
가 2인 경우 level이 2라는 각 그룹의 최신 데이터를 조회하는 요구사항이 있을 수 있다.
id | user_id | level |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 |
1 |
3 |
4 | 2 | 1 |
5 |
2 |
2 |
.
.
.
mysql
에서는 아래 쿼리와 같이 group by
를 사용해서 각 그룹의 id 최대 값을 구하는 서브 쿼리를 조인하여 구할 수 있다.
select t1.id, t1.user_id, t1.level
from test_t as t1
join (select max(id) as id from test_t group by user_id) as t2 on t1.id = t2.id;
다른 방법으로는 아래 쿼리와 같이 self join을 통해 같은 결과를 구할 수 있다.
select t1.id, t1.user_id, t1.level
from test_t as t1
left join test_t as t2 on t1.user_id = t2.user_id and t1.id < t2.id
where t2.id is null;
필자는 user_id
100,000개와 각 user_id
마다 5개씩 총 500,000개 데이터로 테스트를 진행했다. 그리고 user_id
에 index 설정을 하였다.
테스트 결과 user_id
에 index를 설정 한 뒤 확인한 결과, 서브 쿼리를 사용한 첫 번째 쿼리보다 두 번째 쿼리가 성능이 더 뛰어난 것을 확인할 수 있었다.
또한 두 번째 쿼리는 from 절에 서브 쿼리를 사용할 수 없는 JPQL 기반인 querydsl에서도 사용할 수 있기 때문에 좀 더 유용하다.